<?php
/**
 * Created by PhpStorm.
 * User: Administrator
 * Date: 2020-03-07
 * Time: 20:22
 */

namespace zwwl2016\cloudrunner;

class CloudRunner
{
    private $document_root;
    private $sync=false;
    private $requires;
    private $runner;
    private $parameters=[];
    private $result;
    private $is_check_file_needed=false;
    private $broadcast=false;
    private $includeself=false;

    public static $LARAVEL_REQUIRES=['vendor/autoload.php','bootstrap/app.php'];
    public static $PHALCON_REQUIRES=['vendor/autoload.php'
        ,'app/config/router.php'
        ,'app/config/services.php'
        ,'app/config/loader.php'
    ];

    public function __construct()
    {
        $this->requires=self::$LARAVEL_REQUIRES;
    }

    /**
     * @param TransferDomainRequires $requiresType
     * @return $this
     */
    public function setRequires($requiresType)
    {
        switch ($requiresType)
        {
            case TransferDomainRequires::Laravel:
                $this->requires=self::$LARAVEL_REQUIRES;
                break;
            case TransferDomainRequires::Phalcon:
                $this->requires=self::$PHALCON_REQUIRES;
                break;
        }

        return $this;
    }

    public function setRawRequires(array $requireFiles)
    {
        $this->requires=$requireFiles;
        return $this;
    }

    public function setNeedResponse($needResponse=true)
    {
        $this->sync=$needResponse;
        return $this;
    }


    public function setSyncFiles($syncFiles=true)
    {
        $this->is_check_file_needed=$syncFiles;
        return $this;
    }

    public static function Instance()
    {
        return new CloudRunner();
    }

    /**
     * @param array $requires
     * @return CloudRunner
     */
    public function setRunner(iCloudModule $runner)
    {
        $this->runner=$runner;
        return $this;
    }

    public function addParameter(array $parameter)
    {
        $this->parameters[]=$parameter;
        return $this;
    }

    public function setParameters(array $parameters)
    {
        $this->parameters=$parameters;
        return $this;
    }

    public function setBroadcast($broadcast=true)
    {
        $this->broadcast=$broadcast;
        return $this;
    }


    public function setIncludeSelf($includeSelf=true)
    {
        $this->includeself=$includeSelf;
        return $this;
    }


    /**
     * @return CloudRunner
     */
    public function execute()
    {
        $a=$this->msectime();
        $url = "http://127.0.0.1:61111/";
        $data=new TransferDomain();
        $data->class_type=get_class($this->runner);
        $data->sync=$this->sync;
        $data->document_root=dirname(dirname(dirname(__DIR__)));;
        $data->checklist=[];
        $data->includeself=$this->includeself;
        $data->broadcast=$this->broadcast;
        $maxtime=0;
        foreach(get_included_files() as $val) {
            $time = filemtime($val);
            if ($this->is_check_file_needed) {
                $data->checklist[$val] = $time;
            }
            if($time>$maxtime)
            {
                $maxtime=$time;
            }
        }
        $data->updatetick=$maxtime;
        $data->requires=$this->requires;
        $this->result=[];

        $mh = curl_multi_init();
        $curls=[];
        foreach ($this->parameters as $parameter) {
            $data->parameter = $parameter;
            $curl = curl_init();
            curl_setopt($curl, CURLOPT_URL, $url);
            curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, FALSE);
            curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, FALSE);
            curl_setopt($curl, CURLOPT_POST, 1);
            curl_setopt($curl, CURLOPT_POSTFIELDS, json_encode($data));
            curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
            curl_setopt($curl, CURLOPT_HEADER, 0);
            curl_setopt($curl, CURLOPT_CONNECTTIMEOUT, 5);
            curl_setopt($curl, CURLOPT_TIMEOUT, 5);
            curl_setopt($curl, CURLOPT_FOLLOWLOCATION, 1);
            curl_multi_add_handle($mh,$curl);
            $curls[]=$curl;
        }
        $active = null;
        do {
            $mrc = curl_multi_exec($mh, $active);
        }
        while ($mrc == CURLM_CALL_MULTI_PERFORM);
        while ($active && $mrc == CURLM_OK) {
            if (curl_multi_select($mh) != -1) {
                do {
                    $mrc = curl_multi_exec($mh, $active);
                } while ($mrc == CURLM_CALL_MULTI_PERFORM);
            }
        }
        foreach ($curls as $ch) {
            $output= curl_multi_getcontent($ch); // get the content
            $json1=json_decode($output,true);
            if($json1==null)
            {
                $this->result[]=$output;
                curl_multi_remove_handle($mh, $ch);
                continue;
            }
            if(!isset($json1['content']))
            {
                $this->result[]=$json1;
                curl_multi_remove_handle($mh, $ch);
                continue;
            }
            $json2=json_decode($json1['content'],true);
            if($json2==null)
            {
                $this->result[]=$json1['content'];
                curl_multi_remove_handle($mh, $ch);
                continue;
            }
            $this->result[]=$json2;
            curl_multi_remove_handle($mh, $ch);
        }
        curl_multi_close($mh); // close the curl multi handler
        return $this;
    }

    public function getLastResult()
    {
        if(empty($this->result))
        {
            return null;
        }
        return $this->result[count($this->result)-1];
    }

    public function getResultList()
    {
        return $this->result;
    }

    private function msectime() {
        list($msec,$sec)= explode(" ",microtime());
        $msectime=(float)sprintf('%.0f', (floatval($msec) + floatval($sec)) * 1000);
        return $msectime;
    }

}
